package com.ucode.hrm.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.ucode.hrm.controller.service.ApiHrmDataPermissionService;
import com.ucode.hrm.controller.service.ApiHrmExcelHandleService;
import com.ucode.hrm.service.HrmCustomerCompanyService;
import com.ucode.hrm.service.HrmCustomerProjectService;
import com.ucode.hrm.service.HrmEmployeeCostDetailService;
import com.ucode.hrm.service.HrmEmployeeService;
import com.ucode.model.hrm.HrmCustomerCompany;
import com.ucode.model.hrm.HrmCustomerProject;
import com.ucode.model.hrm.HrmEmployeeCostDetail;
import com.ucode.model.hrm.convert.HrmEmployeeCostDetailConvert;
import com.ucode.model.hrm.enums.HrmExcelTemplateEnum;
import com.ucode.model.hrm.vo.HrmEmployeeCostDetailVO;
import com.ucode.tool.annotation.DataPermission;
import com.ucode.tool.annotation.NeedLogin;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.poi.excel.ExcelUtils;
import com.ucode.tool.util.CollectionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;

@Tag(name = "管理后台 - 人力资源系统 - 员工费用明细")
@RestController
@RequestMapping("/hrm/employee-cost-detail")
@Validated
public class HrmEmployeeCostDetailController {
    private static final Log log = LogFactory.get();

    @Resource
    private HrmCustomerProjectService customerProjectService;
    @Resource
    private HrmCustomerCompanyService  customerCompanyService;
    @Resource
    private HrmEmployeeService employeeService;
    @Resource
    private ApiHrmDataPermissionService apiHrmDataPermissionService ;
    @Resource
    private ApiHrmExcelHandleService apiHrmExcelHandleService;
    @Resource
    private HrmEmployeeCostDetailService hrmEmployeeCostDetailService;

    @GetMapping("/page-list")
    @Operation(summary = "获得在职分页列表")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-cost-detail:query')")
    @DataPermission(permissions={"hrm:employee-cost-detail:query"})
    public ResponseResult<Paginator<HrmEmployeeCostDetailVO>> pageList(
            @Schema(description = "客户公司编码") @RequestParam(value = "companyId",required = false) Long companyId,
            @Schema(description = "客户项目编码") @RequestParam(value = "projectId",required = false) Long projectId,
            @Schema(description = "员工名称") @RequestParam(value = "employeeName",required = false) String employeeName,
            @Schema(description = "身份证号") @RequestParam(value = "idCard",required = false) String idCard,
            @Schema(description = "在职地区") @RequestParam(value = "workArea",required = false) String workArea,
            @Schema(description = "批次号") @RequestParam(value = "batchnum",required = false) String batchnum,
            @Schema(description = "费用类型") @RequestParam(value = "costType",required = false) Integer costType,
            @Schema(description = "费用月份区间",example = "[2022-07-01,2022-07-01]")  @RequestParam(value = "feeMonthInterval",required = false) LocalDate[] feeMonthInterval,
            @Schema(description = "页码",example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @Schema(description = "每页记录数",example="5") @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize){

        Map<String,Object> condition = new HashMap<>();
        if(StrUtil.isNotBlank(employeeName))
            condition.put("employeeName", StrUtil.concat(true,"%", employeeName,"%"));
        if(StrUtil.isNotBlank(idCard))
            condition.put("idCard", StrUtil.concat(true,"%", idCard,"%"));
        if(StrUtil.isNotBlank(workArea))
            condition.put("workArea", StrUtil.concat(true,"%", workArea,"%"));
        if(ArrayUtil.isNotEmpty(feeMonthInterval) && feeMonthInterval.length == 2){
            condition.put("startTime",feeMonthInterval[0]);
            condition.put("endTime",feeMonthInterval[1]);
        }

        condition.put("companyId",companyId);
        condition.put("batchnum",batchnum);
        condition.put("costType",costType);

        Set<Long> customerProjectIds = apiHrmDataPermissionService.getCurrentUserCustomerProjectIdsByDataPermission();
        //没有可查看的数据
        if(ObjUtil.isNotNull(customerProjectIds) && customerProjectIds.size() == 0){
            return ResponseResult.success(new Paginator<>());
        }

        //没有权限查看指定项目的数据
        if(ObjUtil.isNotNull(projectId) && ObjUtil.isNotNull(customerProjectIds) && !customerProjectIds.contains(projectId)){
            throw new UcodeServiceException(GlobalResultCodeEnum.UN_DATA_PERMISSION);
        }
        condition.put("projectIds",customerProjectIds);
        condition.put("projectId",projectId);
        condition.put("deltag",false);
        return ResponseResult.success(pageList(condition,pageNum,pageSize));
    }

    private Paginator<HrmEmployeeCostDetailVO> pageList(Map<String,Object> condition, int pageNum, int pageSize) {
        Paginator<HrmEmployeeCostDetail> paginator = hrmEmployeeCostDetailService.queryPageForList(condition,pageSize,pageNum);
        Paginator<HrmEmployeeCostDetailVO> paginatorVO =  HrmEmployeeCostDetailConvert.INSTANCE.convertPage(paginator);


        if(CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> customerCompanyIds =   CollectionUtils.convertSet( paginatorVO.getList(),HrmEmployeeCostDetailVO::getCompanyId);
            Set<Long> projectIds =   CollectionUtils.convertSet( paginatorVO.getList(),HrmEmployeeCostDetailVO::getProjectId);
            Map<Long, HrmCustomerCompany> customerCompanyMap = customerCompanyService.getMap(customerCompanyIds);
            Map<Long, HrmCustomerProject> projectMap = customerProjectService.getMap(projectIds);
            paginatorVO.getList().forEach(item -> {
                HrmCustomerCompany customerCompany = customerCompanyMap.get(item.getCompanyId());
                if(customerCompany != null)
                    item.setCompanyName(customerCompany.getCompanyName());

                HrmCustomerProject project = projectMap.get(item.getProjectId());
                if(project != null)
                    item.setProjectName(project.getProjectName());
            });
        }

        return paginatorVO;
    }

    @GetMapping("/getById/{id}")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH,example = "1024")
    @Operation(summary = "主键获得信息")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-cost-detail:query')")
    public ResponseResult<HrmEmployeeCostDetailVO> getById(@PathVariable(name="id",required=true) Long id){
        HrmEmployeeCostDetail bean = hrmEmployeeCostDetailService.validate(id);
        HrmEmployeeCostDetailVO vo = HrmEmployeeCostDetailConvert.INSTANCE.convert(bean);
        if(ObjUtil.isNotNull(vo.getCompanyId())){
            HrmCustomerCompany customerCompany = customerCompanyService.selectByPrimaryKey(bean.getCompanyId());
            if(customerCompany != null)
                vo.setCompanyName(customerCompany.getCompanyName());
        }

        if(ObjUtil.isNotNull(vo.getProjectId())){
            HrmCustomerProject project = customerProjectService.selectByPrimaryKey(bean.getProjectId());
            if(project != null)
                vo.setProjectName(project.getProjectName());
        }

        return ResponseResult.success(vo);
    }

    @PostMapping("/logic-delete/{id}")
    @Operation(summary = "转移到回收站")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-cost-detail:logic-delete')")
    public ResponseResult<Object> logicDelete(@PathVariable(name="id",required=true) Long id) {
        //逻辑删除
        int i = hrmEmployeeCostDetailService.logicDeletePrimaryKey(id);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @PostMapping("/batch-logic-delete")
    @Operation(summary = "批量转移到回收站")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-cost-detail:logic-delete')")
    public ResponseResult<Boolean> batchLogicDeletePrimaryKey(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                @RequestParam(value = "ids",required = true) List<Long> ids) {
        int i = hrmEmployeeCostDetailService.logicDeleteByPrimaryKeys(ids);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @NeedLogin
    @GetMapping("/export")
    @Operation(summary = "导出")
    public void export(@Schema(description = "客户公司编码") @RequestParam(value = "companyId",required = false) Long companyId,
                       @Schema(description = "客户项目编码") @RequestParam(value = "projectId",required = false) Long projectId,
                       @Schema(description = "员工名称") @RequestParam(value = "employeeName",required = false) String employeeName,
                       @Schema(description = "身份证号") @RequestParam(value = "idCard",required = false) String idCard,
                       @Schema(description = "在职地区") @RequestParam(value = "workArea",required = false) String workArea,
                       @Schema(description = "批次号") @RequestParam(value = "batchnum",required = false) String batchnum,
                       @Schema(description = "费用类型") @RequestParam(value = "costType",required = false) Integer costType,
                       @Schema(description = "费用月份区间",example = "[2022-07-01,2022-07-01]")  @RequestParam(value = "feeMonthInterval",required = false) LocalDate[] feeMonthInterval,
                       HttpServletResponse response) throws IOException {

        Map<String,Object> condition = new HashMap<>();
        if(StrUtil.isNotBlank(employeeName))
            condition.put("employeeName", StrUtil.concat(true,"%", employeeName,"%"));
        if(StrUtil.isNotBlank(idCard))
            condition.put("idCard", StrUtil.concat(true,"%", idCard,"%"));
        if(StrUtil.isNotBlank(workArea))
            condition.put("workArea", StrUtil.concat(true,"%", workArea,"%"));
        if(ArrayUtil.isNotEmpty(feeMonthInterval) && feeMonthInterval.length == 2){
            condition.put("startTime",feeMonthInterval[0]);
            condition.put("endTime",feeMonthInterval[1]);
        }

        condition.put("companyId",companyId);
        condition.put("batchnum",batchnum);
        condition.put("costType",costType);

        Set<Long> customerProjectIds = apiHrmDataPermissionService.getCurrentUserCustomerProjectIdsByDataPermission();

        List<HrmEmployeeCostDetailVO> listVO = null;
        //没有可查看的数据
        if(ObjUtil.isNotNull(customerProjectIds) && customerProjectIds.size() == 0){
            listVO = new ArrayList<>();
        }else {
            //没有权限查看指定项目的数据
            if(ObjUtil.isNotNull(projectId) && ObjUtil.isNotNull(customerProjectIds) && !customerProjectIds.contains(projectId)){
                throw new UcodeServiceException(GlobalResultCodeEnum.UN_DATA_PERMISSION);
            }
            condition.put("projectIds",customerProjectIds);
            condition.put("projectId",projectId);
            condition.put("deltag",false);

            List<HrmEmployeeCostDetail> list = hrmEmployeeCostDetailService.queryObjectForList(condition,0);
            listVO =  HrmEmployeeCostDetailConvert.INSTANCE.convertList(list);
        }

        String fileName = StrUtil.format(HrmExcelTemplateEnum.EMPLOYEE_COST_TEMPLATE.getMessage(), LocalDateTimeUtil.format(LocalDateTimeUtil.now(),"yyyy年MM月dd日HH时mm分ss秒"));

        ExcelUtils.write(response, HrmExcelTemplateEnum.EMPLOYEE_COST_TEMPLATE.getName(), fileName, new HashMap(), listVO);
    }

    @NeedLogin
    @GetMapping("/export-tpl")
    @Operation(summary = "导出模板")
    public void exportTpl(HttpServletResponse response) throws IOException {
        ExcelUtils.write(response, HrmExcelTemplateEnum.EMPLOYEE_COST_TEMPLATE.getName(), HrmExcelTemplateEnum.EMPLOYEE_COST_TEMPLATE.getName(), new HashMap(), new ArrayList<>());
    }

    @PostMapping("/import") // 映射到/api/excel/parse
    @Operation(summary = "导入")
    @PreAuthorize("@usfs.hasPermission('hrm:employee-cost-detail:create')")
    public ResponseResult<Boolean> importEmployeesData(@RequestParam("file") MultipartFile file) throws IOException {

        new Thread(() -> {
            try {
                apiHrmExcelHandleService.importCostDetail(file);
            } catch (Exception e) {
                log.error("导入员工费用表异常了...",e);
            }
        }).start();
        return ResponseResult.success();
    }

}
